package top.kpromise.note.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import top.kpromise.common.base.Result;
import top.kpromise.note.wrapper.HeaderMapRequestWrapper;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class LoginFilter implements Filter {

    @Resource
    private TokenStore tokenStore;

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("LoginFilter init !");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        log.debug("LoginFilter begin...");
        if (!(request instanceof HttpServletRequest)) {
            log.debug("LoginFilter, not is HttpServletRequest, return...");
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        if (httpServletRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
            log.debug("LoginFilter, OPTIONS request, return...");
            chain.doFilter(request, response);
            return;
        }
        String url = httpServletRequest.getRequestURI();
        if (url == null || !url.startsWith("/api")) {
            chain.doFilter(request, response);
            return;
        }

        String accessToken = httpServletRequest.getHeader("Authorization");
        if (accessToken == null) {
            accessToken = httpServletRequest.getHeader("authorization");
        }

        String userName = null;
        OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(accessToken);
        if (null != accessToken && null != oAuth2Authentication) {
            userName = oAuth2Authentication.getName();
            userName = userName.substring(userName.lastIndexOf("_") + 1);
        }
        if (userName == null) {
            log.error("url is {} token is {} oAuth2Authentication is null = {}", url, accessToken, oAuth2Authentication == null);
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            Result<String> result = new Result<>();
            result.error(1101, "用户未登录");
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            ObjectMapper mapper = new ObjectMapper();
            httpServletResponse.getOutputStream().write(mapper.writeValueAsBytes(result));
            return;
        }

        HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(httpServletRequest);
        requestWrapper.addHeader("x_userName", userName);
        log.debug("LoginFilter doFilter...");
        chain.doFilter(requestWrapper, response);
        log.debug("LoginFilter finish...");
    }

    @Override
    public void destroy() {
        log.info("LoginFilter destroy!");
    }
}
